package com.partsoft.dits.dsm;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.util.Assert;

/**
 * 数据源工厂实现基类
 */
public class BaseDatasourceFactory implements DataSourceFactory {

	private Map<String, DataSource> dataSources = Collections.synchronizedMap(new HashMap<String, DataSource>(5));
	
	public DataSource getDataSource(String name) {
		Assert.hasText(name, "未指定数据源名称");
		DataSource ds = (DataSource) this.dataSources.get(name);
		if (ds == null )
			throw new IllegalStateException(String.format("找不到名称为\"%s\"的数据源。", name));
		return ds;
	}
	
	public boolean hasDataSource(String name) {
		Assert.hasText(name, "未指定数据源名称");
		return dataSources.containsKey(name);
	}
	
	public Connection getConnection(String dsName) throws SQLException {
		return DataSourceUtils.getConnection(getDataSource(dsName));
	}

	public DataSource removeDataSource(String dsName) {
		if (!this.dataSources.containsKey(dsName)){
			return null;
		}
		return this.dataSources.remove(dsName);
	}
	
	public boolean testDataSource(String dsName) {
		boolean result = false;
		try{
			Connection conn = getConnection(dsName);
			conn.getMetaData();
			conn.close();
			result = true;
		}catch(Throwable e ){}
		return result;
	}

	public void addDataSource(String name, DataSource ds) {
		Assert.hasText(name, "必须输入数据源名称。");
		Assert.notNull(ds, "数据源不能为空。");
		if (hasDataSource(name)) {
			throw new IllegalArgumentException(String.format("数据源(%s)已经存在，不能重复添加。", name));
		}
		dataSources.put(name, ds);
	}

	public DataSource[] getDataSources() {
		return dataSources.values().toArray(new DataSource[0]);
	}

	public Map<String, DataSource> getNamedDataSource() {
		return Collections.unmodifiableMap(dataSources);
	}

	public String[] getDataSourceNames() {
		return dataSources.keySet().toArray(new String[0]);
	}
	
	protected void clearDatasource() {
		dataSources.clear();
	}
	
}
